/*
 *  userlib.h
 *  
 *
 *  Created by Wang Zhuchen on 2/13/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */

#include "syscall.h"

#define MAX_QUEUE_SIZE 1024

/* return the length of a string */
int mystrlen(char *str) {
	int i = 0;
	while (str[i] != '\0') {
		i++;
	}
	return i;
}

/* convert int to char */
char * int_to_char(int number) {
	char c[12];
	char result[12];
	int i = 0;
	int j = 0;
	if (number == 0) {
		result[0] = '0';
		result[1] = '\0';
		return result;
	}
	if (number < 0) {
		result[i++] = '-';
		number = -number;
	}
	while (number != 0) {
		c[j++] = '0'+number%10;
		number /= 10;
	}
	c[j] = '\0';
	for (j = j-1; j>=0; j--) {
		result[i++] = c[j];
	}
	result[i] = '\0';
	return result;
}

/* myprintf 2.0 */
void mmprintf(char *buf, char *format, int *args, int argc) {
	char *tmp;
	int i = 0;
	int j = 0;
	int k = 0;
	int m;
	while (format[i] != '\0') {
		if (format[i] != '%') {
			buf[k++] = format[i];
		}else {
			switch (format[++i]) {
				case 'd':
					if (j<argc) {	
						m = 0;
						tmp = int_to_char(args[j++]);
						while(tmp[m] != '\0') {
							buf[k++] = tmp[m++];
						}
					}
					break;
				default:
					break;
			}
		}
		i++;
	}
	buf[k] = '\0';
	Write(buf, mystrlen(buf), ConsoleOutput);
}

int myscanf()
{
	char *input;
	char value[3];
	int num;
	int val1;
	int val2;
	int arg[1];
	num=Read(input,2,ConsoleInput);
	
	val1= (int) (input[0]-'0');
	if(input[1]!='\0')
	{
		val2=(int)(input[1]-'0');
		val1=val1*10+val2;
	}
	
	return val1;
}

/* user defined queue type */
typedef struct MyQueue {
	int head;
	int tail;
	int number;
	void *queue[MAX_QUEUE_SIZE];
} MyQueue;

/* Append in the queue */
void InQueue(MyQueue *q, void *elem) {
	if (q->number == 0) {
		/* The queue is empty */
		q->queue[q->head] = elem;
		q->tail = (q->tail+1)%MAX_QUEUE_SIZE;
		q->number ++;
	}else if (q->number == MAX_QUEUE_SIZE) {
		/* The queue is full */
		myprintf("Error: the queue is full\n", 0, 0);
	}else {
		q->queue[q->tail] = elem;
		q->tail = (q->tail+1)%MAX_QUEUE_SIZE;
		q->number ++;
	}
}

/* Remove the first element in the queue */
void * DeQueue(MyQueue *q) {
	void *rv;
	if (q->number > 0) {
		/* The queue is not empty */
		rv = q->queue[q->head];
		q->head = (q->head+1)%MAX_QUEUE_SIZE;
		q->number --;
		return rv;
	}
	myprintf("Error: the queue is empty\n", 0, 0);
	return 0;
}
